# MAIN POINT OF ENTRY FOR R GPU KERNELS
# CONSISTS OF R INTERFACES FOR GPU KERNELS

# load interface source file
dir <- "~/vetter/cse6220/project/kernel/"
dyn.load(paste(dir,"matmult.so",sep=""))
dyn.load(paste(dir,"svd.so",sep=""))

# GPU MATRIX MULTIPLY
gpuMatMult <- function(a,b) {

    #init stuff
    a <- as.matrix(a)
    b <- as.matrix(b)
    if (ncol(a) != nrow(b)) stop("incorrect dimensions")

    #.Call 
    results <- .C("RgpuMatMult", as.integer(0L), as.integer(0L),
        as.single(a), as.integer(nrow(a)), as.integer(ncol(a)),
        as.single(b), as.integer(nrow(b)), as.integer(ncol(b)),
        output = single(nrow(a)*ncol(b)))

    #return results
    cat("gpuMatMult completed.\n")
    matrix(results$output, nrow(a), ncol(b))

}

# GPU SVD
# Perform approximate SVD using steepest gradient descent algorithm
gpuSvd <- function(a, u_approx, v_approx, projdim, thresh, alpha) {
   nobs <- dim(a)[1]
   nfeat <- dim(a)[2]
   
   # perform SVD on this on the GPU
   results <- .C("RgpuSvd", as.single(a), as.integer(nobs),
        as.integer(nfeat), as.single(u_approx), as.single(v_approx),
        u = single(nobs*projdim), v = single(nfeat*projdim),
        as.integer(projdim), as.single(thresh), as.single(alpha))
   
   cat("gpuSvd completed.\n")
   list(t(matrix(results$u,projdim,nobs)), matrix(results$v,projdim,nfeat))
         
}

